﻿using DynamicLogicExpression.Analyzer;
using DynamicLogicExpression.Core;
using System.Text.RegularExpressions;

namespace DynamicLogicExpression;

internal class Program
{
    private static readonly Regex _regex = new("=|>=|>|<=|<|!=");

    private static void Main(string[] _)
    {
        var fake = new FakeCompare() { IntVal = 6, BoolVal = false, Wrapper = new() { Id = 6, InnerWrapper = new() { Id = 5 } } };

        while (true)
        {
            Console.Write("请输入表达式：");
            var command = Console.ReadLine() ?? throw new ArgumentNullException(nameof(_));

            try
            {
                var (left, @operator, right) = ParseCommand(command);

                PropertyNavigation propNav;
                var logicOperator = LogicOperator<FakeCompare>.GetOperator(@operator);

                try
                {
                    propNav = PropertyNavigationAnalyzer.Analyze<FakeCompare>(left);
                }
                catch (InvalidOperationException ex)
                {
                    Console.WriteLine(ex.Message);

                    continue;
                }

                var g = logicOperator.BuildExpression(propNav);

                try
                {
                    var result = g?.Invoke(fake, right);

                    Console.WriteLine(result);
                }
                catch (Exception ex)
                {
                    if (ex.InnerException is not null)
                    {
                        Console.WriteLine(ex.InnerException.Message);
                    }
                    else
                    {
                        Console.WriteLine(ex.Message);
                    }
                }

                Console.WriteLine();
            }
            catch (Exception)
            {
                Console.WriteLine("命令解析失败");

                continue;
            }
        }
    }

    private static (string left, string @operator, string right) ParseCommand(string command)
    {
        var op = _regex.Match(command).Value;

        var slice = command.Split(op);

        return (slice[0].Trim(), op, slice[1].Trim());
    }
}